﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Text;

namespace WFL.Data
{
    public abstract class Context : IContext
    {

        protected abstract string DefaultConnectionString { get; }

        protected object PrivateData
        {
            get 
            {
                TLS tls = TLS.GetCurrent(false);
                if (tls != null)
                {
                    TLS.PrivateStorage storage = tls.GetPrivateStorage(Name, false);
                    if (storage != null)
                    {
                        return storage.Other;
                    }
                }
                return null;
            }
            set
            {
                if (value != null)
                {
                    TLS.GetCurrent().GetPrivateStorage(Name).Other = value;
                }
                else
                {
                    TLS tls = TLS.GetCurrent(false);
                    if (tls != null)
                    {
                        TLS.PrivateStorage storage = tls.GetPrivateStorage(Name, false);
                        if (storage != null)
                        {
                            storage.Other = value;
                        }
                    }
                }
            }
        }

        protected object PublicData
        {
            get
            {
                TLS tls = TLS.GetCurrent(false);
                return tls != null ? tls.PublicData : null;
            }
            set
            {
                if (value != null)
                {
                    TLS.GetCurrent().PublicData = value;
                }
                else
                {
                    TLS tls = TLS.GetCurrent(false);
                    if (tls != null)
                    {
                        tls.PublicData = value;
                    }
                }
            }
        }

        public Context(string name)
        {
            Name = name;
        }

        protected abstract IConnectionProxy Create(string connectionString);

        public IConnectionProxy GetConn()
        {
            TLS tls = TLS.GetCurrent(false);
            if (tls != null)
            {
                TLS.PrivateStorage storage = tls.GetPrivateStorage(Name, false);
                if (storage != null
                    && storage.Connection != null
                    && storage.Connection.State == ConnectionState.Open)
                {
                    return storage.Connection;
                }
            }
            return null;
        }

        protected IConnectionProxy OnSetConn(string connectionString)
        {
            TLS.PrivateStorage storage = TLS.GetCurrent().GetPrivateStorage(Name);
            if (storage.Connection != null
                    && storage.Connection.State == ConnectionState.Open)
            {
                if (storage.Connection.ConnectionString != connectionString)
                {
                    throw new Exception("上下文中存在其它打开的连接");
                }
                return storage.Connection;
            }
            IConnectionProxy iConn = Create(connectionString);
            ConnectionProxy conn = iConn as ConnectionProxy;
            if (conn != null)
            {
                conn.Context = this;
                conn.CreatingMethod = new StackFrame(2).GetMethod();
            }
            storage.Connection = iConn;
            return iConn;
        }


        #region IContext 成员

        public string Name
        {
            get;
            private set;
        }

        public IConnectionProxy SetConn()
        {
            return OnSetConn(DefaultConnectionString);
        }

        public IConnectionProxy SetConn(string connectionString)
        {
            return OnSetConn(connectionString);
        }

        #endregion

    }
}
